Skip to content

Add repository-level vulnerability summary to vulnerabilities command#282

Open
colinmoynes wants to merge 18 commits intomasterfrom
ceng-747-cloudsmith-cli-repo-level-vulnerability-summary-for
Open

Add repository-level vulnerability summary to vulnerabilities command#282
colinmoynes wants to merge 18 commits intomasterfrom
ceng-747-cloudsmith-cli-repo-level-vulnerability-summary-for

Conversation

@colinmoynes
Copy link
Copy Markdown
Contributor

@colinmoynes colinmoynes commented Mar 27, 2026

This pull request introduces improvements to the vulnerability command. It adds a repository-level vulnerability summary capability, allowing users to aggregate and filter vulnerability data across all packages in a repository.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Refactoring
  • Other (please describe)

Additional Notes

@colinmoynes colinmoynes requested a review from a team as a code owner March 27, 2026 16:53
Copilot AI review requested due to automatic review settings March 27, 2026 16:53
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR expands the CLI’s vulnerability reporting to support repository-level aggregation, and also introduces download-command enhancements (filename filtering and multi-package downloads), along with associated version/dependency bumps.

Changes:

  • Add cloudsmith vulnerabilities OWNER/REPO mode to aggregate vulnerability counts across all packages in a repository (with filtering and JSON output).
  • Enhance cloudsmith download with --filename filtering (including glob patterns) and --download-all, plus improved multi-match display.
  • Bump CLI version metadata to 1.16.0 and update cloudsmith-api dependency to 2.0.25.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
cloudsmith_cli/cli/commands/vulnerabilities.py Adds repo-level summary mode, aggregation/filtering, and rich table output.
cloudsmith_cli/core/api/vulnerabilities.py Updates summary table rendering and adjusts scan identifier handling.
cloudsmith_cli/cli/validators.py Adds validator to accept OWNER/REPO[/SLUG_PERM] for vulnerabilities command arg.
cloudsmith_cli/core/download.py Adds filename filtering (server/client side) and refactors multi-match output via rich table; adds resolve-all helper.
cloudsmith_cli/cli/commands/download.py Adds --filename and --download-all, refactors download flow, and adds safe path joining.
cloudsmith_cli/core/tests/test_download.py Adds unit tests for filename filtering, resolve-all behavior, and multi-match display.
cloudsmith_cli/cli/tests/commands/test_download.py Adds integration-style CLI tests for new download flags/behavior.
cloudsmith_cli/cli/commands/upstream.py Adds alpine to supported upstream formats list.
README.md Documents new download flags (--filename, --download-all).
CHANGELOG.md Adds entries for new features/releases (but currently with duplicated 1.14.0 sections).
setup.py / requirements.txt Bumps cloudsmith-api dependency from 2.0.24 to 2.0.25.
cloudsmith_cli/data/VERSION / .bumpversion.cfg Bumps version to 1.16.0.
Comments suppressed due to low confidence (2)

CHANGELOG.md:60

  • The changelog now contains two separate ## [1.14.0] sections (with different dates), which makes it ambiguous which entry is authoritative. Consider consolidating these into a single 1.14.0 section (or correcting the version/date as appropriate).
## [1.14.0] - 2026-03-11

### Added

- Added `vulnerabilities` command to retrieve security scan results for a package
  - Summary View (Default): Displays a high-level count of vulnerabilities broken down by severity (Critical, High, Medium, Low, Unknown).
  - Assessment View `--show-assessment` (`-A`): Provides a detailed breakdown where vulnerabilities are:
    - Grouped by the specific affected upstream package / dependency.
    - Sorted by severity (Critical first).
    - Richly formatted tables.
  - Filtering Capabilities:
    - By Severity: `--severity` Show only specific levels (e.g., just Critical and High).
    - By Status: `--fixable | --non-fixable` Filter to show only "Fixable" vulnerabilities (where a patch exists) or "Non-Fixable" ones.
  - Supports `--output-format json | pretty_json` for programmatic usage

## [1.14.0] - 2026-03-13

### Added

- Added `vulnerabilities` command to retrieve security scan results for a package
  - Summary View (Default): Displays a high-level count of vulnerabilities broken down by severity (Critical, High, Medium, Low, Unknown).
  - Assessment View `--show-assessment` (`-A`): Provides a detailed breakdown where vulnerabilities are:
    - Grouped by the specific affected upstream package / dependency.
    - Sorted by severity (Critical first).
    - Richly formatted tables.
  - Filtering Capabilities:

CHANGELOG.md:23

  • cloudsmith_cli/data/VERSION and .bumpversion.cfg are bumped to 1.16.0, but the new vulnerability summary entry is still under [Unreleased] rather than the 1.16.0 release section. If this change is part of 1.16.0, consider moving it into the ## [1.16.0] section; otherwise consider not bumping the version yet.
## [Unreleased]

### Added

- Added repository-level vulnerability summary (`cloudsmith vulnerabilities OWNER/REPO`)
  - Aggregates scan results across all packages into a single color-coded table
  - Packages sorted by total vulnerability count (descending)
  - Packages without scan results are silently omitted
  - Supports `--severity` and `--fixable/--non-fixable` filters

## [1.16.0] - 2026-03-24

### Added

- Added Alpine Upstream support for managing upstream configurations.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@colinmoynes colinmoynes force-pushed the ceng-747-cloudsmith-cli-repo-level-vulnerability-summary-for branch from 842b05e to df3070c Compare March 27, 2026 17:03
@colinmoynes colinmoynes force-pushed the ceng-747-cloudsmith-cli-repo-level-vulnerability-summary-for branch from df3070c to 0f5ee19 Compare March 27, 2026 17:12
@colinmoynes colinmoynes force-pushed the ceng-747-cloudsmith-cli-repo-level-vulnerability-summary-for branch from da15095 to b6ef8cd Compare April 1, 2026 09:45
Comment on lines +20 to +69
def get_packages_in_repo(opts, owner, repo):
"""Get all packages in a repository, paginating through all pages."""
all_packages = []
page = 1
page_size = 100 # fetch in larger batches for efficiency

try:
while True:
packages, page_info = list_packages(
opts=opts,
owner=owner,
repo=repo,
query=None,
sort=None,
page=page,
page_size=page_size,
)

if packages:
all_packages.extend(packages)

# No page info means single page or no results
if not page_info:
break

current_page = getattr(page_info, "page", page)
total_pages = getattr(page_info, "page_total", 1)

if current_page >= total_pages:
break

page += 1

except Exception as exc:
raise click.ClickException(
f"Failed to list packages for '{owner}/{repo}'. "
f"Please check the owner and repository names are correct. "
f"Detail: {exc}"
) from exc

if not all_packages:
raise click.ClickException(
f"No packages found in '{owner}/{repo}'. "
f"The repository may be empty, or the owner/repo names may be incorrect."
)

return [
(pkg["slug_perm"], pkg.get("name", pkg["slug_perm"]), pkg.get("version", ""))
for pkg in all_packages
]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: why do you need a new function for this instead of doing the same as here? https://github.com/cloudsmith-io/cloudsmith-cli/blob/master/cloudsmith_cli/cli/commands/list_.py#L221

Also if there's a lot of packages this will take A WHILE

Comment on lines +239 to +242
# click.echo(
# f"No vulnerability scan results found for package: {package}", err=True
# )
return None
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change: if you don't need the echo here anymore remove the comment

Comment on lines +397 to +401
slugs = get_packages_in_repo(opts, owner, repo)

repo_summary_rows = _collect_repo_scan_data(
opts, owner, repo, slugs, severity_filter, fixable
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: you should test this out with a repo with a high count of packages, got the feeling it will take a very long time to gather all the data you need. A server-side component might be needed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

4 participants